﻿'
' DotNetNuke® - http://www.dotnetnuke.com
' Copyright (c) 2002-2011
' by DotNetNuke Corporation
'
' Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
' documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
' the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
' to permit persons to whom the Software is furnished to do so, subject to the following conditions:
'
' The above copyright notice and this permission notice shall be included in all copies or substantial portions 
' of the Software.
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
' DEALINGS IN THE SOFTWARE.
'

Imports System
Imports System.IO
Imports System.Xml
Imports System.Web
Imports System.Reflection
Imports DotNetNuke.Entities.Modules
Imports Telerik.Web.UI
Imports DotNetNuke.Framework.Providers
Imports System.Collections.Generic
Imports DotNetNuke.Entities.Users
Imports DotNetNuke.UI.Utilities

Namespace DotNetNuke.Providers.RadEditorProvider

    Public Class EditorProvider
        Inherits DotNetNuke.Modules.HTMLEditorProvider.HtmlEditorProvider

#Region "Private Members"

        Private Const moduleFolderPath As String = "~/DesktopModules/Admin/RadEditorProvider/"
        Private _toolsFile As String = moduleFolderPath + "/ToolsFile/ToolsFile.xml"
        Private _configFile As String = moduleFolderPath + "/ConfigFile/ConfigFile.xml"
        Private _localeFile As String = moduleFolderPath + "/App_LocalResources/RadEditor.Main.resx"

        Private WithEvents _panel As Panel = New Panel()
        Private WithEvents _editor As RadEditor = New RadEditor

        'must override properties
        Private _additionalToolbars As ArrayList
        Private _rootImageDirectory As String = PortalSettings.HomeDirectory

        'other provider specific properties
        Private _enableUpload As Boolean = True
        Private _enableUploadUserFolders As Boolean = False
        'Private _autoCreatePaths As Boolean = False
        'Private _cssFiles As String = String.Empty
        'Private _cssClasses As String = String.Empty
        Private _linksUseTabNames As Boolean = True
        Private _linksUseRelativeUrls As Boolean = True
        Private _ShowPortalLinks As Boolean = True

        'DMX Support
        Private _DMXIntegration As Boolean
        Private _DMXPath As String = "/"


        Private _toolsFileHost As String
        Private _toolsFileAdmin As String
        Private _toolsFileRegistered As String
        Private _toolsFileGuest As String
        'Custom Role Tools Filename
        Private _toolsFileCustomRole As String
        Private _toolsFileRoleNames() As String

        'config file settings
        'Private _isControlInitialized As Boolean = False
        Private _languageSet As Boolean = False
        Private _scripttoload As String = ""

        'DNN data objects
        Private _providerConfiguration As ProviderConfiguration = ProviderConfiguration.GetProviderConfiguration(ProviderType)
        Private objProvider As Provider = CType(_providerConfiguration.Providers(_providerConfiguration.DefaultProvider), Provider)

        Private Const ProviderType As String = "htmlEditor"

#End Region

#Region "Properties"

        Public Overrides Property AdditionalToolbars() As ArrayList
            Get
                Return _additionalToolbars
            End Get
            Set(ByVal Value As ArrayList)
                _additionalToolbars = Value
            End Set
        End Property

        Public Overrides Property ControlID() As String
            Get
                Return _editor.ID
            End Get
            Set(ByVal Value As String)
                _editor.ID = Value
            End Set
        End Property

        Public Overrides Property Height() As Unit
            Get
                Height = _editor.Height
            End Get
            Set(ByVal Value As Unit)
                If (Not Value.IsEmpty) Then
                    _editor.Height = Value
                End If
            End Set
        End Property

        Public Overrides ReadOnly Property HtmlEditorControl() As Control
            Get
                Return CType(_panel, Control)
            End Get
        End Property

        Public Overrides Property RootImageDirectory() As String
            Get
                Return _rootImageDirectory
            End Get
            Set(ByVal Value As String)
                _rootImageDirectory = Value
            End Set
        End Property

        Public Overrides Property Text() As String
            Get
                Return _editor.Content
            End Get
            Set(ByVal Value As String)
                _editor.Content = Value
            End Set
        End Property

        Public Overrides Property Width() As Unit
            Get
                Width = _editor.Width
            End Get
            Set(ByVal Value As Unit)
                If (Not Value.IsEmpty) Then
                    _editor.Width = Value
                End If
            End Set
        End Property

        Public ReadOnly Property ConfigFile() As String
            Get
                'get current user
                Dim objUserInfo As UserInfo = UserController.GetCurrentUserInfo
                'load default tools file
                Dim tempConfigFile As String = _configFile
                'get absolute path of default tools file
                Dim path As String = HttpContext.Current.Server.MapPath(tempConfigFile).ToLower

                Dim rolepath As String = ""
                Dim tabpath As String = ""
                Dim portalpath As String = ""

                'lookup host specific config file
                If Not objUserInfo Is Nothing Then

                    If objUserInfo.IsSuperUser Then


                        rolepath = path.Replace(".xml", ".Host.xml")
                        tabpath = path.Replace(".xml", ".Host.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                        portalpath = path.Replace(".xml", ".Host.PortalId." & PortalSettings.PortalId.ToString & ".xml")

                        If System.IO.File.Exists(tabpath) Then
                            Return tempConfigFile.ToLower.Replace(".xml", ".Host.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                        End If
                        If System.IO.File.Exists(portalpath) Then
                            Return tempConfigFile.ToLower.Replace(".xml", ".Host.PortalId." & PortalSettings.PortalId.ToString & ".xml")
                        End If
                        If System.IO.File.Exists(rolepath) Then
                            Return tempConfigFile.ToLower.Replace(".xml", ".Host.xml")
                        End If

                    End If

                End If

                'lookup admin specific config file
                If (DotNetNuke.Security.PortalSecurity.IsInRole(PortalSettings.AdministratorRoleName)) Then

                    rolepath = path.Replace(".xml", ".Admin.xml")
                    tabpath = path.Replace(".xml", ".Admin.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                    portalpath = path.Replace(".xml", ".Admin.PortalId." & PortalSettings.PortalId.ToString & ".xml")

                    If System.IO.File.Exists(tabpath) Then
                        Return tempConfigFile.ToLower.Replace(".xml", ".Admin.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                    End If
                    If System.IO.File.Exists(portalpath) Then
                        Return tempConfigFile.ToLower.Replace(".xml", ".Admin.PortalId." & PortalSettings.PortalId.ToString & ".xml")
                    End If
                    If System.IO.File.Exists(rolepath) Then
                        Return tempConfigFile.ToLower.Replace(".xml", ".Admin.xml")
                    End If

                End If

                'lookup registered users specific config file
                If (DotNetNuke.Security.PortalSecurity.IsInRole(PortalSettings.RegisteredRoleName)) Then

                    rolepath = path.Replace(".xml", ".Registered.xml")
                    tabpath = path.Replace(".xml", ".Registered.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                    portalpath = path.Replace(".xml", ".Registered.PortalId." & PortalSettings.PortalId.ToString & ".xml")

                    If System.IO.File.Exists(tabpath) Then
                        Return tempConfigFile.ToLower.Replace(".xml", ".Registered.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                    End If
                    If System.IO.File.Exists(portalpath) Then
                        Return tempConfigFile.ToLower.Replace(".xml", ".Registered.PortalId." & PortalSettings.PortalId.ToString & ".xml")
                    End If
                    If System.IO.File.Exists(rolepath) Then
                        Return tempConfigFile.ToLower.Replace(".xml", ".Registered.xml")
                    End If

                End If

                'lookup tab specific config file
                tabpath = path.Replace(".xml", ".TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                If System.IO.File.Exists(tabpath) Then
                    Return tempConfigFile.ToLower.Replace(".xml", ".TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                End If

                'lookup portal specific config file
                portalpath = path.Replace(".xml", ".PortalId." & PortalSettings.PortalId.ToString & ".xml")
                If System.IO.File.Exists(portalpath) Then
                    Return tempConfigFile.ToLower.Replace(".xml", ".PortalId." & PortalSettings.PortalId.ToString & ".xml")
                End If

                'nothing else found, return default file
                Return tempConfigFile

            End Get
        End Property

        Public ReadOnly Property ToolsFile() As String
            Get
                'get current user
                Dim objUserInfo As UserInfo = UserController.GetCurrentUserInfo
                'load default tools file
                Dim tempToolsFile As String = _toolsFile
                'get absolute path of default tools file
                Dim path As String = HttpContext.Current.Server.MapPath(tempToolsFile).ToLower

                Dim rolepath As String = ""
                Dim tabpath As String = ""
                Dim portalpath As String = ""

                'lookup host specific tools file
                If Not objUserInfo Is Nothing Then

                    If objUserInfo.IsSuperUser Then


                        rolepath = path.Replace(".xml", ".Host.xml")
                        tabpath = path.Replace(".xml", ".Host.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                        portalpath = path.Replace(".xml", ".Host.PortalId." & PortalSettings.PortalId.ToString & ".xml")

                        If System.IO.File.Exists(tabpath) Then
                            Return tempToolsFile.ToLower.Replace(".xml", ".Host.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                        End If
                        If System.IO.File.Exists(portalpath) Then
                            Return tempToolsFile.ToLower.Replace(".xml", ".Host.PortalId." & PortalSettings.PortalId.ToString & ".xml")
                        End If
                        If System.IO.File.Exists(rolepath) Then
                            Return tempToolsFile.ToLower.Replace(".xml", ".Host.xml")
                        End If

                    End If

                End If

                'lookup admin specific tools file
                If (DotNetNuke.Security.PortalSecurity.IsInRole(PortalSettings.AdministratorRoleName)) Then

                    rolepath = path.Replace(".xml", ".Admin.xml")
                    tabpath = path.Replace(".xml", ".Admin.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                    portalpath = path.Replace(".xml", ".Admin.PortalId." & PortalSettings.PortalId.ToString & ".xml")

                    If System.IO.File.Exists(tabpath) Then
                        Return tempToolsFile.ToLower.Replace(".xml", ".Admin.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                    End If
                    If System.IO.File.Exists(portalpath) Then
                        Return tempToolsFile.ToLower.Replace(".xml", ".Admin.PortalId." & PortalSettings.PortalId.ToString & ".xml")
                    End If
                    If System.IO.File.Exists(rolepath) Then
                        Return tempToolsFile.ToLower.Replace(".xml", ".Admin.xml")
                    End If

                End If

                'lookup registered users specific tools file
                If (DotNetNuke.Security.PortalSecurity.IsInRole(PortalSettings.RegisteredRoleName)) Then

                    rolepath = path.Replace(".xml", ".Registered.xml")
                    tabpath = path.Replace(".xml", ".Registered.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                    portalpath = path.Replace(".xml", ".Registered.PortalId." & PortalSettings.PortalId.ToString & ".xml")

                    If System.IO.File.Exists(tabpath) Then
                        Return tempToolsFile.ToLower.Replace(".xml", ".Registered.TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                    End If
                    If System.IO.File.Exists(portalpath) Then
                        Return tempToolsFile.ToLower.Replace(".xml", ".Registered.PortalId." & PortalSettings.PortalId.ToString & ".xml")
                    End If
                    If System.IO.File.Exists(rolepath) Then
                        Return tempToolsFile.ToLower.Replace(".xml", ".Registered.xml")
                    End If

                End If

                'lookup tab specific tools file
                tabpath = path.Replace(".xml", ".TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                If System.IO.File.Exists(tabpath) Then
                    Return tempToolsFile.ToLower.Replace(".xml", ".TabId." & PortalSettings.ActiveTab.TabID.ToString & ".xml")
                End If

                'lookup portal specific tools file
                portalpath = path.Replace(".xml", ".PortalId." & PortalSettings.PortalId.ToString & ".xml")
                If System.IO.File.Exists(portalpath) Then
                    Return tempToolsFile.ToLower.Replace(".xml", ".PortalId." & PortalSettings.PortalId.ToString & ".xml")
                End If

                'nothing else found, return default file
                Return tempToolsFile

            End Get
        End Property

#End Region

#Region "Private Helper Methods"

        Private Function AddSlash(ByVal Folderpath As String) As String
            If Folderpath.StartsWith("/") Then
                Return Folderpath.Replace("//", "/")
            Else
                Return "/" & Folderpath
            End If

        End Function

        Private Function RemoveEndSlash(ByVal Folderpath As String) As String
            If Folderpath.EndsWith("/") Then
                Return Folderpath.Substring(0, Folderpath.LastIndexOf("/"))
            Else
                Return Folderpath
            End If
        End Function

        Private Sub PopulateFolder(ByVal folderPath As String, ByVal toolname As String)

            Dim ReadPaths As New System.Collections.ArrayList
            Dim WritePaths As New System.Collections.ArrayList

            If (folderPath = "[PORTAL]") Then
                ReadPaths.Add(RootImageDirectory)
                WritePaths.Add(RootImageDirectory)
            ElseIf folderPath.Length > 0 Then
                Dim path As String = RemoveEndSlash(RootImageDirectory) & AddSlash(folderPath)
                WritePaths.Add(path)
                ReadPaths.Add(path)
            End If

            Dim _readPaths As String() = CType(ReadPaths.ToArray(GetType(String)), String())
            Dim _writePaths As String() = CType(WritePaths.ToArray(GetType(String)), String())

            Select Case toolname
                Case "ImageManager"
                    SetFolderPaths(_editor.ImageManager, _readPaths, _writePaths, True, True)
                Case "FlashManager"
                    SetFolderPaths(_editor.FlashManager, _readPaths, _writePaths, True, True)
                Case "MediaManager"
                    SetFolderPaths(_editor.MediaManager, _readPaths, _writePaths, True, True)
                Case "DocumentManager"
                    SetFolderPaths(_editor.DocumentManager, _readPaths, _writePaths, True, True)
                Case "TemplateManager"
                    SetFolderPaths(_editor.TemplateManager, _readPaths, _writePaths, True, True)
                Case "SilverlightManager"
                    SetFolderPaths(_editor.SilverlightManager, _readPaths, _writePaths, True, True)
            End Select


        End Sub

        Public Overrides Sub AddToolbar()
            'must override...
        End Sub

        Private Sub SetFolderPaths(ByVal manager As FileManagerDialogConfiguration, ByVal readPaths As String(), ByVal writePaths As String(), ByVal setDeletePath As Boolean, ByVal setUploadPath As Boolean)
            manager.ViewPaths = readPaths
            If setUploadPath Then
                manager.UploadPaths = writePaths
            Else
                manager.UploadPaths = Nothing
            End If
            If setDeletePath Then
                manager.DeletePaths = writePaths
            Else
                manager.DeletePaths = Nothing
            End If
        End Sub

        Private Function AddLink(ByVal objTab As DotNetNuke.Entities.Tabs.TabInfo, ByRef parent As EditorLink) As EditorLink
            Dim linkUrl As String = String.Empty
            If (Not objTab.DisableLink) Then
                If (_linksUseTabNames) Then
                    Dim linkFormat As String = "http://{0}/Default.aspx?TabName={1}"
                    linkUrl = String.Format(linkFormat, PortalSettings.PortalAlias.HTTPAlias, HttpUtility.UrlEncode(objTab.TabName))
                Else
                    linkUrl = objTab.FullUrl
                End If
                If (_linksUseRelativeUrls AndAlso (linkUrl.StartsWith("http://") Or linkUrl.StartsWith("https://"))) Then
                    Dim linkIndex As Integer = linkUrl.IndexOf("/", 8)
                    If (linkIndex > 0) Then
                        linkUrl = linkUrl.Substring(linkIndex)
                    End If
                End If
            End If
            Dim newLink As EditorLink = New EditorLink(objTab.TabName.Replace("\", "\\"), linkUrl)
            parent.ChildLinks.Add(newLink)
            Return newLink
        End Function

        Private Sub AddChildLinks(ByVal TabId As Integer, ByRef links As EditorLink)
            Dim objTab As DotNetNuke.Entities.Tabs.TabInfo
            Dim tc As New TabController
            Dim tabs As List(Of DotNetNuke.Entities.Tabs.TabInfo) = TabController.GetPortalTabs(PortalSettings.PortalId, Null.NullInteger, False, "", True, False, True, True, False)
            For Each objTab In tabs
                If objTab.ParentId = TabId Then
                    'these are viewable children (current user's rights)
                    If objTab.HasChildren = True Then
                        'has more children
                        AddChildLinks(objTab.TabID, AddLink(objTab, links))
                    Else
                        AddLink(objTab, links)
                    End If
                End If
            Next
        End Sub

        Private Sub AddPortalLinks()

            Dim objTab As DotNetNuke.Entities.Tabs.TabInfo
            Dim portalLinks As EditorLink = New EditorLink("Portal Links", String.Empty)
            _editor.Links.Add(portalLinks)

            'Add links to custom link menu
            Dim tc As New TabController
            Dim tabs As List(Of DotNetNuke.Entities.Tabs.TabInfo) = TabController.GetPortalTabs(PortalSettings.PortalId, Null.NullInteger, False, "", True, False, True, True, False)
            For Each objTab In tabs
                'check permissions and visibility of current tab
                If (objTab.Level = 0) Then
                    If objTab.HasChildren Then
                        'is a root tab, and has children
                        AddChildLinks(objTab.TabID, AddLink(objTab, portalLinks))
                    Else
                        AddLink(objTab, portalLinks)
                    End If
                End If
            Next

        End Sub

#End Region

#Region "Public Methods"

        Public Overrides Sub Initialize()

            _editor.ToolsFile = ToolsFile
            _editor.EnableViewState = False
            _editor.ExternalDialogsPath = moduleFolderPath + "Dialogs/"

            If ConfigFile <> String.Empty Then

                Dim xmlDoc As XmlDocument = GetValidConfigFile()
                Dim colorConverter As New WebColorConverter()
                Dim items As New ArrayList()

                If Not xmlDoc Is Nothing Then

                    For Each node As XmlNode In xmlDoc.DocumentElement.ChildNodes

                        If node.Attributes Is Nothing OrElse node.Attributes("name") Is Nothing OrElse node.InnerText.Length = 0 Then
                            Continue For
                        End If

                        Dim propertyName As String = node.Attributes("name").Value
                        Dim propValue As String = node.InnerText
                        'use reflection to set all string and bool properties
                        SetEditorProperty(propertyName, propValue)
                        'the following collections are handled by the tools file now:
                        'CssFiles, Colors, Symbols, Links, FontNames, FontSizes, Paragraphs, RealFontSizes
                        'CssClasses, Snippets, Languages
                        Select Case propertyName
                            Case "ScriptToLoad"
                                Dim path As String = Context.Request.MapPath(PortalSettings.ActiveTab.SkinPath) & node.InnerText
                                If System.IO.File.Exists(path) Then
                                    _scripttoload = PortalSettings.ActiveTab.SkinPath & node.InnerText
                                End If
                            Case "ContentFilters"
                                _editor.ContentFilters = DirectCast([Enum].Parse(GetType(EditorFilters), node.InnerText), EditorFilters)
                                Exit Select
                            Case "ToolbarMode"
                                _editor.ToolbarMode = DirectCast(EditorToolbarMode.Parse(GetType(EditorToolbarMode), node.InnerText, True), EditorToolbarMode)
                                Exit Select
                            Case "EditModes"
                                _editor.EditModes = DirectCast(EditModes.Parse(GetType(EditModes), node.InnerText, True), EditModes)
                                Exit Select
                            Case "StripFormattingOptions"
                                _editor.StripFormattingOptions = DirectCast(EditorStripFormattingOptions.Parse(GetType(EditorStripFormattingOptions), node.InnerText, True), EditorStripFormattingOptions)
                                Exit Select
                            Case "MaxImageSize"
                                _editor.ImageManager.MaxUploadFileSize = Integer.Parse(node.InnerText)
                                Exit Select
                            Case "MaxFlashSize"
                                _editor.FlashManager.MaxUploadFileSize = Integer.Parse(node.InnerText)
                                Exit Select
                            Case "MaxMediaSize"
                                _editor.MediaManager.MaxUploadFileSize = Integer.Parse(node.InnerText)
                                Exit Select
                            Case "MaxDocumentSize"
                                _editor.DocumentManager.MaxUploadFileSize = Integer.Parse(node.InnerText)
                                Exit Select
                            Case "MaxTemplateSize"
                                _editor.TemplateManager.MaxUploadFileSize = Integer.Parse(node.InnerText)
                                Exit Select
                            Case "MaxSilverlightSize"
                                _editor.SilverlightManager.MaxUploadFileSize = Integer.Parse(node.InnerText)
                                Exit Select
                            Case "FileBrowserContentProviderTypeName"
                                _editor.ImageManager.ContentProviderTypeName = node.InnerText
                                _editor.FlashManager.ContentProviderTypeName = node.InnerText
                                _editor.MediaManager.ContentProviderTypeName = node.InnerText
                                _editor.DocumentManager.ContentProviderTypeName = node.InnerText
                                _editor.TemplateManager.ContentProviderTypeName = node.InnerText
                                _editor.SilverlightManager.ContentProviderTypeName = node.InnerText
                                Exit Select
                            Case "SpellAllowAddCustom"
                                ' RadSpell properties
                                _editor.SpellCheckSettings.AllowAddCustom = Boolean.Parse(node.InnerText)
                                Exit Select
                            Case "SpellCustomDictionarySourceTypeName"
                                _editor.SpellCheckSettings.CustomDictionarySourceTypeName = node.InnerText
                                Exit Select
                            Case "SpellCustomDictionarySuffix"
                                _editor.SpellCheckSettings.CustomDictionarySuffix = node.InnerText
                                Exit Select
                            Case "SpellDictionaryPath"
                                _editor.SpellCheckSettings.DictionaryPath = node.InnerText
                                Exit Select
                            Case "SpellDictionaryLanguage"
                                _editor.SpellCheckSettings.DictionaryLanguage = node.InnerText
                                Exit Select
                            Case "SpellEditDistance"
                                _editor.SpellCheckSettings.EditDistance = Integer.Parse(node.InnerText)
                                Exit Select
                            Case "SpellFragmentIgnoreOptions"
                                'SpellCheckSettings.FragmentIgnoreOptions = (FragmentIgnoreOptions)Enum.Parse(typeof(FragmentIgnoreOptions), node.InnerText, true);
                                Exit Select
                            Case "SpellCheckProvider"
                                _editor.SpellCheckSettings.SpellCheckProvider = DirectCast([Enum].Parse(GetType(SpellCheckProvider), node.InnerText, True), SpellCheckProvider)
                                Exit Select
                            Case "SpellWordIgnoreOptions"
                                _editor.SpellCheckSettings.WordIgnoreOptions = DirectCast([Enum].Parse(GetType(WordIgnoreOptions), node.InnerText, True), WordIgnoreOptions)
                                Exit Select
                            Case "ImagesPath"
                                PopulateFolder(node.InnerText, "ImageManager")
                                Exit Select
                            Case "FlashPath"
                                PopulateFolder(node.InnerText, "FlashManager")
                                Exit Select
                            Case "MediaPath"
                                PopulateFolder(node.InnerText, "MediaManager")
                                Exit Select
                            Case "DocumentsPath"
                                PopulateFolder(node.InnerText, "DocumentManager")
                                Exit Select
                            Case "TemplatePath"
                                PopulateFolder(node.InnerText, "TemplateManager")
                                Exit Select
                            Case "SilverlightPath"
                                PopulateFolder(node.InnerText, "SilverlightManager")
                                Exit Select
                            Case "ContentAreaMode"
                                _editor.ContentAreaMode = [Enum].Parse(GetType(EditorContentAreaMode), node.InnerText)
                                Exit Select
                            Case "LinksUseTabNames"
                                Try
                                    _linksUseTabNames = Boolean.Parse(node.InnerText)
                                Catch
                                End Try
                            Case "LinksUseRelativeUrls"
                                Try
                                    _linksUseRelativeUrls = Boolean.Parse(node.InnerText)
                                Catch
                                End Try
                            Case "ShowPortalLinks"
                                Try
                                    _ShowPortalLinks = Boolean.Parse(node.InnerText)
                                Catch
                                End Try
                            Case "CssFile"
                                Dim path As String = Context.Request.MapPath(PortalSettings.ActiveTab.SkinPath) & node.InnerText
                                If System.IO.File.Exists(path) Then
                                    _editor.CssFiles.Clear()
                                    _editor.CssFiles.Add(PortalSettings.ActiveTab.SkinPath & node.InnerText)
                                Else
                                    path = Context.Request.MapPath(PortalSettings.HomeDirectory) & node.InnerText
                                    If System.IO.File.Exists(path) Then
                                        _editor.CssFiles.Clear()
                                        _editor.CssFiles.Add(PortalSettings.HomeDirectory & node.InnerText)
                                    End If
                                End If

                            Case "DMXIntegration"
                                _DMXIntegration = Convert.ToBoolean(node.InnerText)
                            Case "DMXPath"
                                _DMXPath = node.InnerText
                            Case Else
                                ' end of RadSpell properties
                                If propertyName.EndsWith("Filters") Then
                                    items.Clear()

                                    If node.HasChildNodes Then
                                        If node.ChildNodes.Count = 1 Then
                                            If node.ChildNodes.Item(0).NodeType = XmlNodeType.Text Then
                                                items.Add(node.InnerText)
                                            ElseIf node.ChildNodes.Item(0).NodeType = XmlNodeType.Element Then
                                                items.Add(node.ChildNodes.Item(0).InnerText)
                                            End If
                                        Else
                                            For Each itemnode As XmlNode In node.ChildNodes
                                                items.Add(itemnode.InnerText)
                                            Next
                                        End If
                                    End If

                                    Dim itemsArray As String() = DirectCast(items.ToArray(GetType(String)), String())
                                    Select Case propertyName

                                        Case "ImagesFilters"
                                            _editor.ImageManager.SearchPatterns = ApplySearchPatternFilter(itemsArray)
                                            Exit Select

                                        Case "FlashFilters"
                                            _editor.FlashManager.SearchPatterns = ApplySearchPatternFilter(itemsArray)
                                            Exit Select

                                        Case "MediaFilters"
                                            _editor.MediaManager.SearchPatterns = ApplySearchPatternFilter(itemsArray)
                                            Exit Select

                                        Case "DocumentsFilters"
                                            _editor.DocumentManager.SearchPatterns = ApplySearchPatternFilter(itemsArray)
                                            Exit Select

                                        Case "TemplateFilters"
                                            _editor.TemplateManager.SearchPatterns = ApplySearchPatternFilter(itemsArray)
                                            Exit Select

                                        Case "SilverlightFilters"
                                            _editor.SilverlightManager.SearchPatterns = ApplySearchPatternFilter(itemsArray)
                                            Exit Select

                                    End Select

                                End If

                        End Select
                    Next

                Else
                    'could not load config
                End If

            Else
                'could not load config (config file property empty?)
            End If

        End Sub

        Private Function ApplySearchPatternFilter(ByVal patterns As String()) As String()
            Dim hostWhiteList = DotNetNuke.Entities.Host.Host.AllowedExtensionWhitelist
            
            If (patterns.Length = 1 AndAlso patterns(0) = "*.*") Then
                'todisplaystring converts to a "*.xxx, *.yyy" format which is then split for return
                Return hostWhiteList.ToDisplayString().Split(",")
            Else
                Dim returnPatterns As New List(Of String)

                For Each pattern As String In patterns
                    If hostWhiteList.IsAllowedExtension(pattern.Substring(1)) Then
                        returnPatterns.Add(pattern)
                    End If
                Next

                Return returnPatterns.ToArray
            End If

        End Function

        Protected Sub Panel_Init(ByVal sender As Object, ByVal e As EventArgs) Handles _panel.Init


            'fix for allowing childportal (tabid must be in querystring!)
            Dim PortalPath As String = ""
            Try
                PortalPath = _editor.TemplateManager.ViewPaths(0)
            Catch
            End Try
            PortalPath = PortalPath.Replace(PortalSettings.HomeDirectory, "").Replace("//", "/")
            Dim strSaveTemplateDialogPath As String = _panel.Page.ResolveUrl(moduleFolderPath + "Dialogs/SaveTemplate.aspx?Path=" & PortalPath & "&TabId=" & PortalSettings.ActiveTab.TabID.ToString)



            Dim strRegisterDialogScriptPath As String = _panel.Page.ResolveUrl(moduleFolderPath + "js/RegisterDialogs.js")

            _panel.Controls.Add(New LiteralControl("<script type=""text/javascript"" src=""" & strRegisterDialogScriptPath & """></script>"))

            If _scripttoload <> "" Then
                _panel.Controls.Add(New LiteralControl("<script type=""text/javascript"" src=""" + _panel.Page.ResolveUrl(_scripttoload) + """></script>"))
            End If

            'add save template dialog var
            _panel.Controls.Add(New LiteralControl("<script type=""text/javascript"">var __textEditorSaveTemplateDialog = """ & strSaveTemplateDialogPath & """;</script>"))

            If _DMXIntegration Then

                Dim strDMXDialogPath As String = _panel.Page.ResolveUrl("~/DesktopModules/DMXBrowser.ContentProvider/DMXBrowser.aspx?Path=" & _DMXPath & "&TabId=" & PortalSettings.ActiveTab.TabID.ToString)

                'add dmx browser dialog var
                _panel.Controls.Add(New LiteralControl("<script type=""text/javascript"">var __textEditorDMXManagerDialog = """ & strDMXDialogPath & """;</script>"))

                'add css classes for save template tool
                _panel.Controls.Add(New LiteralControl("<style type=""text/css"">.reTool .DMXManager { background-image: url('" + _panel.Page.ResolveUrl(moduleFolderPath + "images/DMXManager.gif") + "'); }</style>"))

            End If



            'add css classes for save template tool
            _panel.Controls.Add(New LiteralControl("<style type=""text/css"">.reTool_text .SaveTemplate, .reTool .SaveTemplate { background-image: url('" + _panel.Page.ResolveUrl(moduleFolderPath + "images/save.png") + "') !important; }</style>"))
            _panel.Controls.Add(New LiteralControl("<style type=""text/css"">.reTool .TemplateOptions { background-image: url('" + _panel.Page.ResolveUrl(moduleFolderPath + "images/templates.png") + "') !important; }</style>"))
            _panel.Controls.Add(New LiteralControl("<style type=""text/css"">.reTool_text .TemplateManager, .reTool .TemplateManager { background-image: url('" + _panel.Page.ResolveUrl(moduleFolderPath + "images/templates.png") + "') !important; background-position: left top !important; }</style>"))
            _panel.Controls.Add(New LiteralControl("<style type=""text/css"">.reTool .InsertOptions { background-image: url('" + _panel.Page.ResolveUrl(moduleFolderPath + "images/Attachment.png") + "') !important; }</style>"))

            'add editor control to panel
            _panel.Controls.Add(_editor)

        End Sub

        Protected Sub Panel_Load(ByVal sender As Object, ByVal e As EventArgs) Handles _panel.Load

            'register the override CSS file to take care of the DNN default skin problems
            Dim cssOverrideUrl As String = _panel.Page.ResolveUrl(moduleFolderPath & "/Css/EditorOverride.css")
            Dim pageScriptManager As ScriptManager = ScriptManager.GetCurrent(_panel.Page)
            If (Not (pageScriptManager Is Nothing)) AndAlso (pageScriptManager.IsInAsyncPostBack) Then
                _panel.Controls.Add(New LiteralControl(String.Format("<link title='RadEditor Stylesheet' type='text/css' rel='stylesheet' href='{0}'></link>", _panel.Page.Server.HtmlEncode(cssOverrideUrl))))
            ElseIf Not (_panel.Page.Header Is Nothing) Then
                Dim link As HtmlLink = New HtmlLink()
                link.Href = cssOverrideUrl
                link.Attributes.Add("type", "text/css")
                link.Attributes.Add("rel", "stylesheet")
                link.Attributes.Add("title", "RadEditor Stylesheet")
                _panel.Page.Header.Controls.Add(link)
            End If

        End Sub

        Protected Sub Panel_PreRender(ByVal sender As Object, ByVal e As EventArgs) Handles _panel.PreRender
            Try
                'Exceptions are causing a stream of other NullReferenceExceptions
                'as a work around, track the exception and print out
                '                If (Not IsNothing(_TrackException)) Then
                '                    _panel.Controls.Clear()
                '                    _panel.Controls.Add(New LiteralControl(_TrackException.Message))
                '                End If

                Dim parentModule As PortalModuleBase = ControlUtilities.FindParentControl(Of PortalModuleBase)(HtmlEditorControl)
                Dim moduleid As Integer = CType(If(parentModule Is Nothing, -1, parentModule.ModuleId), Integer)
                Dim portalId As Integer = CType(If(parentModule Is Nothing, -1, parentModule.PortalId), Integer)
                Dim tabId As Integer = CType(If(parentModule Is Nothing, -1, parentModule.TabId), Integer)
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorModuleId", moduleid, True)
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorTabId", tabId, True)
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorPortalId", portalId, True)
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorHomeDirectory", PortalSettings.HomeDirectory, True)
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorPortalGuid", PortalSettings.GUID.ToString, True)
                ClientAPI.RegisterClientVariable(HtmlEditorControl.Page, "editorEnableUrlLanguage", PortalSettings.EnableUrlLanguage, True)

            Catch ex As Exception
                Throw ex
            End Try
        End Sub

        Protected Sub RadEditor_Load(ByVal sender As Object, ByVal e As EventArgs) Handles _editor.Load
            Dim editorPage As Page = _panel.Page

            'set language
            If (Not _languageSet) Then 'language might have been set by config file

                Dim localizationLang As String = "en-US" 'use teleriks internal fallback language

                'first check portal settings
                If IsLocaleAvailable(PortalSettings.DefaultLanguage) Then
                    'use only if resource file exists
                    localizationLang = PortalSettings.DefaultLanguage
                End If

                'then check if language cookie is present
                If Not (editorPage.Request.Cookies("language") Is Nothing) Then
                    Dim cookieValue As String = editorPage.Request.Cookies.Get("language").Value
                    If IsLocaleAvailable(cookieValue) Then
                        'only use locale if resource file is present
                        localizationLang = cookieValue
                    End If
                End If

                'set new value
                If (localizationLang <> String.Empty) Then
                    _editor.Language = localizationLang
                End If

            End If

            _editor.LocalizationPath = moduleFolderPath & "/App_LocalResources/"

            If _ShowPortalLinks Then
                AddPortalLinks()
            End If

            'set editor /spell properties to work with child portals
            _editor.SpellCheckSettings.DictionaryPath = moduleFolderPath & "RadSpell/"
            'again: fix for allowing childportals (tabid must be in querystring!)
            _editor.DialogHandlerUrl = _panel.Page.ResolveUrl(moduleFolderPath & "DialogHandler.aspx?tabid=" & PortalSettings.ActiveTab.TabID.ToString())
            '_editor.SpellCheckSettings.AjaxUrl = moduleFolderPath.Replace("~", "") & "SpellCheckHandler.ashx?tabid=" & PortalSettings.ActiveTab.TabID.ToString()
            _editor.SpellCheckSettings.AjaxUrl = _panel.Page.ResolveUrl(moduleFolderPath & "SpellCheckHandler.ashx?tabid=" & PortalSettings.ActiveTab.TabID.ToString())

        End Sub

        Private Function IsLocaleAvailable(ByVal Locale As String) As Boolean

            If Locale.ToLower = "en-us" Then
                Locale = ""
            End If

            Dim path As String = HttpContext.Current.Server.MapPath(_localeFile.ToLower.Replace(".resx", Locale & ".resx"))

            If System.IO.File.Exists(path) Then
                'resource file exists
                Return True
            End If

            'does not exist
            Return False

        End Function

#End Region

#Region "Config File related code"

        Private Function GetXmlFilePath(ByVal path As String) As String
            'In case the file is declared as "http://someservername/somefile.xml"
            If path.StartsWith("http://") OrElse path.StartsWith("https://") Then
                Return path
            End If
            Dim convertedPath As String = Context.Request.MapPath(path)
            If File.Exists(convertedPath) Then
                Return convertedPath
            Else
                Return path
            End If
        End Function

        Protected Function GetValidConfigFile() As XmlDocument
            Dim xmlConfigFile As New XmlDocument()
            Try
                xmlConfigFile.Load(GetXmlFilePath(ConfigFile))
            Catch generatedExceptionName As Exception
                Throw New Exception("Invalid Configuration File:" + ConfigFile)
            End Try
            Return xmlConfigFile
        End Function

        Private Sub SetEditorProperty(ByVal propertyName As String, ByVal propValue As String)
            Dim pi As PropertyInfo = _editor.GetType().GetProperty(propertyName)
            If Not (pi Is Nothing) Then
                If pi.PropertyType.Equals(GetType(String)) Then
                    pi.SetValue(_editor, propValue, Nothing)
                ElseIf pi.PropertyType.Equals(GetType(Boolean)) Then
                    pi.SetValue(_editor, Boolean.Parse(propValue), Nothing)
                ElseIf pi.PropertyType.Equals(GetType(Unit)) Then
                    pi.SetValue(_editor, Unit.Parse(propValue), Nothing)
                ElseIf pi.PropertyType.Equals(GetType(Integer)) Then
                    pi.SetValue(_editor, Integer.Parse(propValue), Nothing)
                End If
            End If
            If (propertyName = "Language") Then
                _languageSet = True
            End If
        End Sub


#End Region

    End Class

End Namespace